import re
import numpy as np
import matplotlib.pyplot as plt

# ==================== 配置文件路径 ====================
log_path = r"c:\Users\LSQ_CX\Desktop\下午日志详细分析\control_node_3170_63942(1).log"

# 正则表达式
pattern_mode_switch = re.compile(r"手动切换模式模式_")           # 触发条件
pattern_curr_rid = re.compile(r"curr_tracking_rid:\{(.+?)\}")     # 匹配字典内容
pattern_time = re.compile(r"(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}),(\d{3})")  # 时间头 2025-09-12 17:03:20,663

# 存储数据：[(timestamp, lat, lon), ...]
tracking_data = []

current_timestamp = None
start_recording = False
last_lat_lon = None  # 用于去重

# ==================== 解析日志 ====================
with open(log_path, 'r', encoding='utf-8') as f:
    for line in f:
        # === 检查是否触发模式切换 ===
        if not start_recording and pattern_mode_switch.search(line):
            print("检测到‘手动切换模式_纯视觉’，从此行后开始记录 curr_tracking_rid")
            start_recording = True
            continue  # 不处理这一行本身的数据

        if not start_recording:
            continue  # 跳过未触发前的所有行

        # === 提取时间戳（日志行开头的时间）===
        time_match = pattern_time.search(line)
        if not time_match:
            continue  # 没有时间戳跳过
        date_str, ms_str = time_match.groups()
        sec_part = np.datetime64(f"{date_str}.{ms_str}")
        # 转为浮点型秒（相对于第一个有效时间）
        if current_timestamp is None:
            ref_time = sec_part.astype('datetime64[ms]').astype('float') * 0.001
        current_timestamp = (sec_part.astype('datetime64[ms]').astype('float') * 0.001) - ref_time

        # === 提取 curr_tracking_rid ===
        rid_match = pattern_curr_rid.search(line)
        if not rid_match:
            continue

        content = rid_match.group(1)
        # 使用正则提取 lat_serial 和 lon_serial
        lat_match = re.search(r"'lat_serial':\s*([-\d.]+)", content)
        lon_match = re.search(r"'lon_serial':\s*([-\d.]+)", content)
        if not lat_match or not lon_match:
            continue

        try:
            lat = float(lat_match.group(1))
            lon = float(lon_match.group(1))
        except ValueError:
            continue

        # === 去重：只有当 (lat, lon) 发生变化时才记录 ===
        if last_lat_lon is not None:
            if abs(lat - last_lat_lon[0]) < 1e-8 and abs(lon - last_lat_lon[1]) < 1e-8:
                continue  # 与上一次相同，忽略重复
        last_lat_lon = (lat, lon)

        tracking_data.append((current_timestamp, lat, lon))

# 转为 NumPy 数组
if len(tracking_data) == 0:
    print("在规定切换的模式后未提取到任何 curr_tracking_rid 数据。")
else:
    tracking_data = np.array(tracking_data)
    print(f"✅ 共提取到 {len(tracking_data)} 次有效的经纬度更新")

    # ==================== 计算每秒更新频率 ====================
    times = tracking_data[:, 0]  # 相对时间（秒）
    if len(times) == 0:
        print("无有效时间数据")
    else:
        # 时间范围
        t_min = int(np.floor(times[0]))
        t_max = int(np.ceil(times[-1]))
        bins = np.arange(t_min, t_max + 2)  # 每秒一个 bin [0,1), [1,2), ...

        # 统计每个时间窗口内的更新次数
        freq_counts, _ = np.histogram(times, bins=bins)

        # 对应的时间中心点
        bin_centers = (bins[:-1] + bins[1:]) / 2

        # ==================== 绘图 ====================
        plt.figure(figsize=(12, 6))
        plt.bar(bin_centers, freq_counts, width=0.8, color='skyblue', edgecolor='navy', alpha=0.7)
        plt.xlabel("Time Since Mode Switch (s)")
        plt.ylabel("Update Frequency (times per second)")
        plt.title("GPS Update Frequency of curr_tracking_rid\n(After '纯视觉' Mode Activated)")
        plt.grid(True, axis='y', linestyle='--', alpha=0.6)

        # 标注平均频率
        avg_freq = np.mean(freq_counts)
        plt.axhline(avg_freq, color='red', linestyle='--', linewidth=2, label=f'Average: {avg_freq:.2f} Hz')
        plt.legend()

        # 设置整数 x 轴刻度
        plt.xticks(np.arange(t_min, t_max + 1, step=max(1, (t_max - t_min) // 10)))

        plt.tight_layout()
        plt.show()

        # 输出统计信息
        print(f"📊 统计结果：")
        print(f"   时间区间: {t_min} s → {t_max} s")
        print(f"   平均更新频率: {avg_freq:.2f} 次/秒 (Hz)")
        print(f"   最高频率: {freq_counts.max()} 次/秒")
        print(f"   最低频率: {freq_counts.min()} 次/秒（非零最小值: {freq_counts[freq_counts > 0].min() if any(freq_counts > 0) else 0})")